#ifndef RISCV_H
#define RISCV_H

#include <stdint.h>

// --------------------------
// RISC-V 控制寄存器定义（机器模式）
// --------------------------

// 机器状态寄存器（mstatus）
#define MSTATUS_MIE (1 << 3)   // 机器模式全局中断使能位
#define MSTATUS_MPIE (1 << 7)  // 保存的机器模式中断使能位（用于中断嵌套）
#define MSTATUS_SPP (1 << 8)   // 超级模式之前的特权级

// 机器中断使能寄存器（mie）
#define MIE_MSIE (1 << 3)  // 机器模式软件中断使能
#define MIE_MTIE (1 << 7)  // 机器模式定时器中断使能
#define MIE_MEIE (1 << 11) // 机器模式外部中断使能（PLIC相关）

// 机器陷阱向量寄存器（mtvec）模式
#define MTVEC_DIRECT 0x0   // 直接模式（所有中断跳转到同一入口）
#define MTVEC_VECTORED 0x1 // 向量模式（不同中断跳转到不同入口）

// --------------------------
// 寄存器读写内联函数（通过CSR指令）
// --------------------------

/**
 * 读取CSR寄存器
 * @param csr: CSR寄存器编号
 * @return 寄存器值
 */
static inline uint64_t r_csr(uint16_t csr) {
    uint64_t value;
    __asm__ __volatile__("csrr %0, %1" : "=r"(value) : "i"(csr));
    return value;
}

/**
 * 写入CSR寄存器
 * @param csr: CSR寄存器编号
 * @param value: 要写入的值
 */
static inline void w_csr(uint16_t csr, uint64_t value) {
    __asm__ __volatile__("csrw %0, %1" : : "i"(csr), "r"(value));
}

/**
 * 读-修改-写CSR寄存器（置位指定位）
 * @param csr: CSR寄存器编号
 * @param mask: 要置位的掩码
 * @return 修改前的寄存器值
 */
static inline uint64_t rw_csr_set(uint16_t csr, uint64_t mask) {
    uint64_t value;
    __asm__ __volatile__("csrrs %0, %1, %2" : "=r"(value) : "i"(csr), "r"(mask));
    return value;
}

/**
 * 读-修改-写CSR寄存器（清除指定位）
 * @param csr: CSR寄存器编号
 * @param mask: 要清除的掩码
 * @return 修改前的寄存器值
 */
static inline uint64_t rw_csr_clear(uint16_t csr, uint64_t mask) {
    uint64_t value;
    __asm__ __volatile__("csrrc %0, %1, %2" : "=r"(value) : "i"(csr), "r"(mask));
    return value;
}

// --------------------------
// 常用寄存器操作封装
// --------------------------

/**
 * 读取机器状态寄存器（mstatus）
 */
static inline uint64_t r_mstatus(void) {
    uint64_t x;
    __asm__ __volatile__("csrr %0, mstatus" : "=r" (x));
    return x;
}

/**
 * 写入机器状态寄存器（mstatus）
 */
static inline void w_mstatus(uint64_t x) {
    __asm__ __volatile__("csrw mstatus, %0" : : "r" (x));
}

/**
 * 读取机器中断使能寄存器（mie）
 */
static inline uint64_t r_mie(void) {
    uint64_t x;
    __asm__ __volatile__("csrr %0, mie" : "=r" (x));
    return x;
}

/**
 * 写入机器中断使能寄存器（mie）
 */
static inline void w_mie(uint64_t x) {
    __asm__ __volatile__("csrw mie, %0" : : "r" (x));
}

/**
 * 读取机器陷阱向量寄存器（mtvec）
 */
static inline uint64_t r_mtvec(void) {
    uint64_t x;
    __asm__ __volatile__("csrr %0, mtvec" : "=r" (x));
    return x;
}

/**
 * 写入机器陷阱向量寄存器（mtvec）
 */
static inline void w_mtvec(uint64_t x) {
    __asm__ __volatile__("csrw mtvec, %0" : : "r" (x));
}

/**
 * 读取机器异常程序计数器（mepc）
 * 保存中断/异常发生时的指令地址
 */
static inline uint64_t r_mepc(void) {
    uint64_t x;
    __asm__ __volatile__("csrr %0, mepc" : "=r" (x));
    return x;
}

/**
 * 写入机器异常程序计数器（mepc）
 * 用于修改中断/异常返回地址
 */
static inline void w_mepc(uint64_t x) {
    __asm__ __volatile__("csrw mepc, %0" : : "r" (x));
}

/**
 * 读取机器异常原因寄存器（mcause）
 * 保存中断/异常的原因代码
 */
static inline uint64_t r_mcause(void) {
    uint64_t x;
    __asm__ __volatile__("csrr %0, mcause" : "=r" (x));
    return x;
}

/**
 * 写入机器异常原因寄存器（mcause）
 */
static inline void w_mcause(uint64_t x) {
    __asm__ __volatile__("csrw mcause, %0" : : "r" (x));
}

/**
 * 读取机器陷阱值寄存器（mtval）
 * 保存导致异常的地址或其他信息
 */
static inline uint64_t r_mtval(void) {
    uint64_t x;
    __asm__ __volatile__("csrr %0, mtval" : "=r" (x));
    return x;
}

/**
 * 写入机器陷阱值寄存器（mtval）
 */
static inline void w_mtval(uint64_t x) {
    __asm__ __volatile__("csrw mtval, %0" : : "r" (x));
}

/**
 * 读取机器中断待处理寄存器（mip）
 */
static inline uint64_t r_mip(void) {
    uint64_t x;
    __asm__ __volatile__("csrr %0, mip" : "=r" (x));
    return x;
}

/**
 * 写入机器中断待处理寄存器（mip）
 */
static inline void w_mip(uint64_t x) {
    __asm__ __volatile__("csrw mip, %0" : : "r" (x));
}

/**
 * 读取机器hart ID寄存器（mhartid）
 * 返回当前CPU核心的ID
 */
static inline uint32_t r_mhartid(void) {
    uint64_t x;
    __asm__ __volatile__("csrr %0, mhartid" : "=r" (x));
    return (uint32_t)x;
}

// --------------------------
// CPU控制指令
// --------------------------

/**
 * 等待中断指令（wfi）
 * 让CPU进入低功耗状态，等待中断唤醒
 */
static inline void wfi(void) {
    __asm__ __volatile__("wfi" : : : "memory");
}

/**
 * 内存屏障指令（fence）
 * 确保内存访问的顺序性
 */
static inline void fence(void) {
    __asm__ __volatile__("fence" : : : "memory");
}

/**
 * 指令屏障（fence.i）
 * 刷新指令缓存
 */
static inline void fence_i(void) {
    __asm__ __volatile__("fence.i" : : : "memory");
}

/**
 * 从机器模式返回（mret）
 * 注意：此函数通常在汇编中使用，C代码中少用
 */
static inline void mret(void) {
    __asm__ __volatile__("mret");
}

#endif  // RISCV_H

